/*
* ============================================================================
*  Name        : sea_tree.cpp
*  Part of     : Finite state machine utilities
*  Description : Tree implementation
*  Version     : %version: %
*  
*
* ============================================================================
*/
#include "sea_tree.h"
#include "sea_iterator.h"

/**
 * @file sea_tree.cpp
 *
 * @ingroup AssociationUtilities
 */
using namespace sea;

// -------------------------------------------------------------------------------------------------
// Ctor
// -------------------------------------------------------------------------------------------------
Tree::Tree( Object* root_obj ):
    m_root( root_obj )
{
}

// -------------------------------------------------------------------------------------------------
// Dtor
// -------------------------------------------------------------------------------------------------
Tree::~Tree( )
{
    // Kill the tree
    if ( m_root == NULL )
    {
        return;
    }

    detach_all_branches( m_root.get( ) );
}

// -------------------------------------------------------------------------------------------------
// Attach child to parent by specified ID. Root has an extra reference
// -------------------------------------------------------------------------------------------------
bool Tree::attach( Object* parent, Object* child, Association id )
{
    if ( !child )
    {
        return false;
    }

    if ( m_root == NULL ) 
    {
        m_root = parent;
    }
    else 
    if ( m_root == child ) 
    {
        m_root = parent;
    }

    if ( child->attach_right_of( parent, id ) )
    {
        return true;
    }
    return false;
}

// -------------------------------------------------------------------------------------------------
// Detach branch specified by an id
// -------------------------------------------------------------------------------------------------
bool Tree::detach_branch( Object* obj, Association id )
{
    if ( !obj )
    {
        return false;
    }

    bool ret = false;

    // Get local reference since obj can be destroyed by futher detaching from the 
    // existing associations
    sea::aref safe( obj );

    for( VIterator< > it( obj, id ); *it; ) 
    {
        Object* obj = *it;
        it++;
        detach_branch( obj, id );
    }

    if ( id.is_any( ) )
    {
        ret = obj->detach_all( );
    }
    else
    {
        ret = obj->detach( id );
    }

    return ret;
}

// -------------------------------------------------------------------------------------------------
